package org.example.ding.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 菜品实体类
 * 包含菜品基本信息、营养成分和属性特征
 */
@Entity
@Table(name = "dishes")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dish {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 100)
    @NotBlank(message = "菜品名称不能为空")
    @Size(max = 100, message = "菜品名称长度不能超过100个字符")
    private String name;

    @Column(columnDefinition = "TEXT")
    @Size(max = 1000, message = "菜品描述长度不能超过1000个字符")
    private String description;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id")
    private DishCategory category;

    // 营养成分 (每100g)
    @DecimalMin(value = "0.0", message = "卡路里必须大于等于0")
    @Column(nullable = false, precision = 8, scale = 2)
    private BigDecimal calories;

    @DecimalMin(value = "0.0", message = "蛋白质含量必须大于等于0")
    @Column(nullable = false, precision = 8, scale = 2)
    private BigDecimal protein;

    @DecimalMin(value = "0.0", message = "碳水化合物含量必须大于等于0")
    @Column(nullable = false, precision = 8, scale = 2)
    private BigDecimal carbohydrates;

    @DecimalMin(value = "0.0", message = "脂肪含量必须大于等于0")
    @Column(nullable = false, precision = 8, scale = 2)
    private BigDecimal fat;

    @DecimalMin(value = "0.0", message = "纤维含量必须大于等于0")
    @Column(precision = 8, scale = 2)
    private BigDecimal fiber = BigDecimal.ZERO;

    @DecimalMin(value = "0.0", message = "钠含量必须大于等于0")
    @Column(precision = 8, scale = 2)
    private BigDecimal sodium = BigDecimal.ZERO;

    // 菜品属性
    @Enumerated(EnumType.STRING)
    @Column(name = "spice_level")
    private SpiceLevel spiceLevel = SpiceLevel.NONE;

    @Column(name = "taste_profile", columnDefinition = "JSON")
    private String tasteProfile;

    @Enumerated(EnumType.STRING)
    @Column(name = "cooking_method")
    private CookingMethod cookingMethod;

    @Column(name = "suitable_meals", columnDefinition = "JSON")
    private String suitableMeals;

    // 统计信息
    @DecimalMin(value = "0.0", message = "受欢迎程度必须大于等于0")
    @DecimalMax(value = "10.0", message = "受欢迎程度不能超过10")
    @Column(name = "popularity_score", precision = 5, scale = 2)
    private BigDecimal popularityScore = BigDecimal.ZERO;

    @Min(value = 0, message = "点餐次数必须大于等于0")
    @Column(name = "order_count")
    private Integer orderCount = 0;

    @Column(name = "image_url")
    @Size(max = 255, message = "图片URL长度不能超过255个字符")
    private String imageUrl;

    @DecimalMin(value = "0.0", message = "价格必须大于等于0")
    @Column(precision = 8, scale = 2)
    private BigDecimal price;

    @Column(name = "is_available")
    private Boolean isAvailable = true;

    @CreationTimestamp
    @Column(name = "created_at", updatable = false)
    private LocalDateTime createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    // 关联关系
    @OneToMany(mappedBy = "dish", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<OrderRecord> orderRecords;

    // 移除了UserPreference的关联，简化数据模型

    /**
     * 辣度枚举
     */
    public enum SpiceLevel {
        NONE("不辣"),
        MILD("微辣"),
        MEDIUM("中辣"),
        HOT("辣"),
        VERY_HOT("超辣");

        private final String description;

        SpiceLevel(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 烹饪方式枚举
     */
    public enum CookingMethod {
        STEAMED("蒸"),
        BOILED("煮"),
        FRIED("炒"),
        GRILLED("烤"),
        BAKED("烘焙"),
        RAW("生食");

        private final String description;

        CookingMethod(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 计算指定份量的营养成分
     */
    public NutritionInfo calculateNutrition(BigDecimal portionSize) {
        if (portionSize == null || portionSize.compareTo(BigDecimal.ZERO) <= 0) {
            portionSize = BigDecimal.ONE;
        }

        return new NutritionInfo(
            calories.multiply(portionSize),
            protein.multiply(portionSize),
            carbohydrates.multiply(portionSize),
            fat.multiply(portionSize),
            fiber.multiply(portionSize),
            sodium.multiply(portionSize)
        );
    }

    /**
     * 营养信息内部类
     */
    @Data
    @AllArgsConstructor
    public static class NutritionInfo {
        private BigDecimal calories;
        private BigDecimal protein;
        private BigDecimal carbohydrates;
        private BigDecimal fat;
        private BigDecimal fiber;
        private BigDecimal sodium;
    }

    /**
     * 增加点餐次数
     */
    public void incrementOrderCount() {
        this.orderCount = (this.orderCount == null ? 0 : this.orderCount) + 1;
        // 更新受欢迎程度 (简单算法，可以后续优化)
        updatePopularityScore();
    }

    /**
     * 更新受欢迎程度
     */
    private void updatePopularityScore() {
        // 简单的受欢迎程度计算：基于点餐次数，最大值为10
        if (orderCount != null && orderCount > 0) {
            double score = Math.min(10.0, Math.log(orderCount + 1) * 2);
            this.popularityScore = BigDecimal.valueOf(score).setScale(2, BigDecimal.ROUND_HALF_UP);
        }
    }
}
